﻿using Engine.Sgml;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using System.Text;
using Engine.Sgml.Validation.Rules;
using Engine.Sgml.Parser;
using System.Diagnostics;
using Engine.Dtd.Schema;

namespace Engine.Sgml.Test {
    /// <summary>
    ///This is a test class for SgmlStreamTest and is intended
    ///to contain all SgmlStreamTest Unit Tests
    ///</summary>
    [TestClass()]
    public class SgmlStreamTest {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
                }
            set {
                testContextInstance = value;
                }
            }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestMethod]
        public void DetectGenerationOfGCTest() {
            char[] chars = new char[100000];
            for (int i = 0; i < chars.Length; i++) {
                chars[i] = 'a';
                }
            string x = new string(chars);
            int generationNumber = GC.GetGeneration(x);
            Assert.IsTrue(generationNumber == 2);
            }

        [TestMethod]
        public void DetectEncodingTest() {
            string filePath = @"C:\Documents and Settings\Kir\Рабочий стол\SGML Document\Engine.Sgml.Test\Document Samples";
            MemoryStream ms = new MemoryStream(File.ReadAllBytes(Path.Combine(filePath, "Detect Encoding Test 0100.xml")));
            SgmlStream stream = new SgmlStream(ms, Encoding.UTF8);
            ValidationRuleCollection rules = new ValidationRuleCollection(new DNameCollection());
            rules.Add(ValidationRuleCollection.EmptyRule);
            Context context = new Context(new Configuration.ValidatorBehavior(), SgmlDocument.LoadSchemaFromManifest(), new TraceSource("TEST"));
            Encoding e = stream.DetectEncoding(context, new SElement(".", SgmlNodeType.Document));
            Assert.AreEqual<string>(e.BodyName, "iso-8859-1");
            Assert.AreEqual(stream.Encoding, e);
            }


        /// <summary>
        ///A test for SgmlStream Constructor
        ///</summary>
        [TestMethod()]
        public void CreateMementoTest() {
            Stream stream = new MemoryStream(100);
            byte b = 1;
            int count = 98;
            while (--count >= 0) {
                stream.WriteByte(b);
                b++;
                }
            stream.Position = 0;

            Encoding defaultEncoding = Encoding.UTF8;
            SgmlStream target = new SgmlStream(stream, defaultEncoding, 10);
            SgmlStream.Memento memento = new SgmlStream.Memento(target);
            memento.Restore();

            StringBuilder builder = new StringBuilder();
            count = 5;
            while (--count >= 0)
                builder.Append(target.Read());
            string partBefore = builder.ToString();
            memento = new SgmlStream.Memento(target);
            count = 6;
            while (--count >= 0)
                target.Read();
            memento.Restore();
            builder.Clear();
            count = 5;
            while (--count >= 0)
                builder.Append(target.Read());
            string partAfter = builder.ToString();
            Assert.AreEqual<string>(string.Concat(partBefore, partAfter), "12345678910");

            stream.Position = 0;
            target = new SgmlStream(stream, defaultEncoding, 10);
            count = 10;
            builder.Clear();
            while (--count >= 0)
                builder.Append(target.Read());
            partBefore = builder.ToString();
            memento = new SgmlStream.Memento(target);
            count = 6;
            while (--count >= 0)
                target.Read();
            builder.Clear();
            memento.Restore();
            count = 5;
            while (--count >= 0)
                builder.Append(target.Read());
            partAfter = builder.ToString();
            Assert.AreEqual<string>("123456789101112131415", string.Concat(partBefore, partAfter));

            count = 5;
            builder.Clear();
            while (--count >= 0)
                builder.Append(target.Read());
            partBefore = builder.ToString();
            memento = new SgmlStream.Memento(target);
            count = 80;
            while (--count >= 0)
                target.Read();
            builder.Clear();
            memento.Restore();
            count = 5;
            while (--count >= 0)
                builder.Append(target.Read());
            partAfter = builder.ToString();
            Assert.AreEqual<string>("16171819202122232425", string.Concat(partBefore, partAfter));

            count = 66;
            while (--count >= 0)
                target.Read();
            builder.Clear();
            count = 4;
            while (--count >= 0)
                builder.Append(target.Read());
            memento = new SgmlStream.Memento(target);
            partBefore = builder.ToString();
            count = 3;
            while (--count >= 0)
                target.Read();

            memento.Restore();
            count = 3;
            builder.Clear();
            while (--count >= 0)
                builder.Append(target.Read());
            partAfter = builder.ToString();
            Assert.AreEqual<string>("92939495969798", string.Concat(partBefore, partAfter));

            memento = new SgmlStream.Memento(target);
            memento.Restore();
            }
        }
    }
